package com.elitah.usbnet;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.telephony.TelephonyManager;

public final class Tools {

	public static void setWifiEnabled(Context context, boolean enabled) {
		WifiManager wm = (WifiManager) context
				.getSystemService(Context.WIFI_SERVICE);
		if (null != wm) {
			wm.setWifiEnabled(false);
		}
	}

	public static void setMobileDataEnabled(Context context, boolean enabled) {
		final ConnectivityManager cm = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		Class<?> conmanClass;
		try {
			conmanClass = Class.forName(cm.getClass().getName());
			final Field iConnectivityManagerField = conmanClass
					.getDeclaredField("mService");
			iConnectivityManagerField.setAccessible(true);
			final Object iConnectivityManager = iConnectivityManagerField
					.get(cm);
			final Class<?> iConnectivityManagerClass = Class
					.forName(iConnectivityManager.getClass().getName());
			final Method setMobileDataEnabledMethod = iConnectivityManagerClass
					.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
			setMobileDataEnabledMethod.setAccessible(true);
			setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
		} catch (Exception e) {
			InvokeHandlerException(e);
		}
	}

	public static int getMobileDataStatus(Context context) {
		TelephonyManager tm = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		return tm.getDataState();
	}

	public static boolean waitMobileData(Context context, int timeout,
			boolean status) {
		int value = status ? TelephonyManager.DATA_CONNECTED
				: TelephonyManager.DATA_DISCONNECTED;
		while (value != Tools.getMobileDataStatus(context)) {
			if (0 == timeout) {
				return false;
			}
			try {
				Thread.sleep(1000);
				timeout--;
			} catch (InterruptedException e) {
				return false;
			}
		}
		return true;
	}

	public static void InvokeHandlerException(Exception e0) {
		if (e0 instanceof InvocationTargetException) {
			try {
				throw ((InvocationTargetException) e0).getTargetException();
			} catch (Throwable e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		} else {
			e0.printStackTrace();
		}
	}

	public static boolean haveRoot() {
		if (0 == execRootCmdSilent("echo test")) {
			return true;
		}
		return false;
	}

	public static String execRootCmd(String cmd) {
		StringBuffer sb = new StringBuffer();

		DataOutputStream dos = null;
		BufferedReader br = null;

		try {
			Process p = Runtime.getRuntime().exec("su");

			dos = new DataOutputStream(p.getOutputStream());
			br = new BufferedReader(new InputStreamReader(p.getInputStream()));

			dos.writeBytes(cmd + "\n");
			dos.flush();
			dos.writeBytes("exit\n");
			dos.flush();
			String line = null;
			while ((line = br.readLine()) != null) {
				sb.append(line).append('\n');
			}
			p.waitFor();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (dos != null) {
				try {
					dos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return sb.toString();
	}

	public static int execRootCmdSilent(String cmd) {
		int result = -1;
		DataOutputStream dos = null;

		try {
			Process p = Runtime.getRuntime().exec("su");
			dos = new DataOutputStream(p.getOutputStream());

			dos.writeBytes(cmd + "\n");
			dos.flush();
			dos.writeBytes("exit\n");
			dos.flush();
			p.waitFor();
			result = p.exitValue();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (dos != null) {
				try {
					dos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}
}
